﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class LayCheckhole : HYExternalCommand
	{
		public override Result HYExecute(ref string tranName)
		{
			ViewPlan viewPlan = base.Doc.ActiveView as ViewPlan;
			if (viewPlan == null || (int)viewPlan.ViewType != 1)
			{
				YJKMessageBox.Show("请在楼层平面下运行该命令！");
				return Autodesk.Revit.UI.Result.Failed;
			}
			string text = "";
			FamilySymbol familySymbolByName = YJKRevitTools.GetFamilySymbolByName("Accessory", "立管检查口", base.Doc, ref text);
			ISelectionFilter selectionFilter = new RiserPipeFilter();
			Result result;
			for (;;)
			{
				try
				{
					Reference reference = base.Sel.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, selectionFilter, "请选择一根立管");
					XYZ globalPoint = reference.GlobalPoint;
					Pipe pipe = base.Doc.GetElement(reference) as Pipe;
					XYZ project = new YJKPiping<Pipe>(pipe).GetProject(globalPoint, false);
					Level genLevel = base.Doc.ActiveView.GenLevel;
					double num = this.getLevelOffset(genLevel.Name, base.Doc) * 304.8 + 1000.0;
					XYZ xyz = new XYZ(project.X, project.Y, num / 304.8);
					XYZ mosthighPoint = this.getMosthighPoint(pipe);
					XYZ hyendPoint;
					if (((pipe.Location as LocationCurve).Curve as Line).GetEndPoint(0).Z > ((pipe.Location as LocationCurve).Curve as Line).GetEndPoint(1).Z)
					{
						hyendPoint = ((pipe.Location as LocationCurve).Curve as Line).GetEndPoint(1);
					}
					else
					{
						hyendPoint = ((pipe.Location as LocationCurve).Curve as Line).GetEndPoint(0);
					}
					if (mosthighPoint.Z < xyz.Z)
					{
						YJKMessageBox.Information("选择的立管在该楼层的高度不足1米，无法布置检查口");
					}
					else if (hyendPoint.Z >= xyz.Z)
					{
						YJKMessageBox.Information("选择的立管无法布置检查口，请检查是否已经布置过检查口");
					}
					else if (mosthighPoint.Z * 304.8 > num)
					{
						List<Pipe> list = new List<Pipe>();
						list = new YJKPiping<Pipe>(pipe).Separate(xyz);
						Connector closerConnector = this.getCloserConnector(list[0], xyz);
						Connector closerConnector2 = this.getCloserConnector(list[1], xyz);
						UnifiedModified.ActivateFamilySymbol(familySymbolByName);
						FamilyInstance familyInstance = base.Doc.Create.NewFamilyInstance(xyz, familySymbolByName, base.Doc.ActiveView.GenLevel, (Autodesk.Revit.DB.Structure.StructuralType)0);
						base.Doc.Regenerate();
						if (familyInstance.GetParameter("公称直径") != null && !familyInstance.GetParameter("公称直径").IsReadOnly)
						{
							familyInstance.GetParameter("公称直径").Set((closerConnector.Owner as Pipe).Diameter);
						}
						List<Connector> elementAllConnector = YJKRevitTools.GetElementAllConnector(familyInstance);
						if (elementAllConnector[0].Origin.Z > elementAllConnector[1].Origin.Z)
						{
							if (this.getMosthighPoint(list[0]).Z > this.getMosthighPoint(list[1]).Z)
							{
								elementAllConnector[0].ConnectTo(closerConnector);
								elementAllConnector[1].ConnectTo(closerConnector2);
							}
							else
							{
								elementAllConnector[0].ConnectTo(closerConnector2);
								elementAllConnector[1].ConnectTo(closerConnector);
							}
						}
						else if (this.getMosthighPoint(list[0]).Z < this.getMosthighPoint(list[1]).Z)
						{
							elementAllConnector[0].ConnectTo(closerConnector);
							elementAllConnector[1].ConnectTo(closerConnector2);
						}
						else
						{
							elementAllConnector[0].ConnectTo(closerConnector2);
							elementAllConnector[1].ConnectTo(closerConnector);
						}
						XYZ xyz2 = new XYZ(0.0, 0.0, 1.0);
						ElementTransformUtils.MoveElement(base.Doc, familyInstance.Id, xyz2);
						xyz2 = new XYZ(0.0, 0.0, -1.0);
						ElementTransformUtils.MoveElement(base.Doc, familyInstance.Id, xyz2);
					}
					else
					{
						YJKMessageBox.Information("你选择的立管在该层不能布置清扫口");
					}
					continue;
				}
				catch (Autodesk.Revit.Exceptions.OperationCanceledException)
				{
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
				catch (Exception ex)
				{
					YJKMessageBox.Information(ex.Message);
					result = Autodesk.Revit.UI.Result.Failed;
				}
				break;
			}
			return result;
		}

		private XYZ getMosthighPoint(Pipe pipe)
		{
			if ((pipe.Location as LocationCurve).Curve.GetEndPoint(0).Z <= (pipe.Location as LocationCurve).Curve.GetEndPoint(1).Z)
			{
				return (pipe.Location as LocationCurve).Curve.GetEndPoint(1);
			}
			return (pipe.Location as LocationCurve).Curve.GetEndPoint(0);
		}

		private Connector getCloserConnector(Pipe pipe, XYZ xyz)
		{
			return new YJKPiping<Pipe>(pipe).GetCloseConnector(xyz, false);
		}

		private double getLevelOffset(string level, Autodesk.Revit.DB.Document doc)
		{
			return this.Get_Level(doc, level).ProjectElevation;
		}

		private Level Get_Level(Autodesk.Revit.DB.Document document, string pipingSystemTypeName)
		{
			ICollection<Element> elementByClass = YJKElementFilter.GetElementByClass(typeof(Level), document);
			return this.GetElementSameName(elementByClass, pipingSystemTypeName) as Level;
		}

		private Element GetElementSameName(ICollection<Element> collection, string elemName)
		{
			Element result = null;
			foreach (Element element in collection)
			{
				if (element != null && element.Name == elemName)
				{
					result = element;
				}
			}
			return result;
		}

		private double zCoord(double offset)
		{
			return offset / 0.3048;
		}
	}
}
